#version 460
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_EXT_buffer_reference2 : require
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require

#include "../../../../core/shader_binding_ID.h"
#include "../../../../core/shader_std.h" 
#include "../../../../core/shader_built_in_functions.h"
#include "../../../../core/shader_ray.h"

#include "../../../../core/shader_mesh.h" 
#include "../../../../core/shader_taster_geomFaceAttr.h"

//#include "../../../../core/shader_taster_geomFaceAttr.h"

layout(triangles) in;
layout(triangle_strip, max_vertices=64) out;


layout(location = 0) in vec4 vColor[];
layout(location = 1) in vec3 vNormal[];
layout(location = 2) in vec3 vCamera[][4];
layout(location = 8) in uint vVertIndexID[];
layout(location = 9) in uint vMeshOffset[];
layout(location = 20) in uint vFaceOffset[];

layout(location = DEF_BINDING_LocationBindID_Vert) in vec3 vVert[];
layout(location = DEF_BINDING_LocationBindID_FaceAttr) in S_Geom_MeshDrawProp vFaceAttr[];
layout(location = DEF_BINDING_LocationBindID_RotMat) in mat4 vTranformMat[];

//layout(location = DEF_BINDING_TasterBindID_MeshAtt) in uint vMeshAtt_Offset[];
//layout(location = DEF_BINDING_TasterBindID_MaterialAtt) in uint vMaterialAtt_Offset[];

layout(binding = DEF_BINDING_ObMesh, scalar) readonly buffer B_ObMesh { S_ObMesh m_ObMesh[]; };
layout(binding = DEF_BINDING_TasterBindID_Face, scalar) readonly buffer B_Faces { S_FaceElement m_Face[]; };
layout(binding = DEF_BINDING_TasterBindID_TexCoord, scalar) readonly buffer B_TexCoord { vec2 m_TexCoord[]; };
layout(binding = DEF_BINDING_TasterBindID_TexIndex, scalar) readonly buffer B_TexIndex { uvec3 m_TexIndex[]; };

layout(binding = DEF_BINDING_Render_GlobalParam, scalar) readonly buffer B_GlobalParam { S_GlobalParam gGlobalParam; };
layout(binding = DEF_BINDING_Material_AttrIndex, scalar) readonly buffer Material_CustomAttr { S_CustomAttr CustomAttrPtr[]; } MaterialCA_GParam;
layout(binding = DEF_BINDING_Face_AttrIndex, scalar) readonly buffer Face_CustomAttr { S_CustomAttr CustomAttrPtr[]; } customAttr_GParam;

in gl_PerVertex {
	vec4 gl_Position;
	float gl_PointSize;
}gl_in[];


layout(location = 0) out vec4 outColor;
layout(location = 1) out vec3 outNormal;
layout(location = 2) out vec3 outCamera[4];
layout(location = 8) flat out uint outPrimitiveID;
layout(location = 9) flat out uint outMeshOffset;
layout(location = 10) out vec3 outBarycentrics;
layout(location = 11) out vec2 outUV[4];
//layout(location = 6) out float outDepthScale;

out gl_PerVertex {
	vec4	gl_Position;
};

layout(location = DEF_BINDING_LocationBindID_Vert) out vec3 gVert;
layout(location = DEF_BINDING_TasterBindID_MaterialID) out flat S_FaceAttr Element;

#include "../../../../core/shader_taster_edge.h"


void main(void){
	//outPrimitiveID = 0;
	//return;
	//S_ObMesh      Resource_ObMesh = m_ObMesh[vMeshOffset[0]];
	primitiveID = gl_PrimitiveIDIn + vFaceOffset[0];
	//primitiveID = gl_PrimitiveIDIn;
	face = m_Face[vFaceAttr[0].Offset_Face + primitiveID];

	
	vec3 edgeA = (vVert[1] - vVert[0]);
	vec3 edgeB = (vVert[2] - vVert[0]);
	vec3 edgeC = (vVert[1] - vVert[2]);
	vec3 Normal = normalize(cross(edgeA, edgeB));

	S_Geom_MeshDrawProp AttrOffset = vFaceAttr[0];
	vec3 Co = (vVert[0] + vVert[1] + vVert[2]) / 3;

	uvec3 AdjacencyID = g_Face_AdjacencyID[AttrOffset.Offset_Face_AdjacencyID + primitiveID];
	uvec3 NormalAID = AdjacencyID + AttrOffset.Offset_Face_Normal;
	uvec3 CenterAID = AdjacencyID + AttrOffset.Offset_Face_Center;

	mat3 normalMat = mat3(vTranformMat[0]);
	vec3 viewLine = vCamera[0][1] - (vTranformMat[0] * vec4(Co, 1)).xyz;
	float nv = dot(normalMat * Normal, viewLine);

	
	if (nv <= 0) return;

	lineWidth[0] = 0.05;
	lineWidth[1] = 0.05;
	lineWidth[2] = 0.05;

	viewLine = vCamera[0][1] - (vTranformMat[0] * vec4(g_Face_Center[CenterAID.x], 1)).xyz;
	if (dot(viewLine, normalMat * g_Face_Normal[NormalAID.x]) <= 0.0) {
		f_line_build(gl_in[0].gl_Position, gl_in[1].gl_Position, vColor[0], vColor[1], lineWidth[0], lineWidth[1]);
	}

	viewLine = vCamera[0][1] - (vTranformMat[1] * vec4(g_Face_Center[CenterAID.y], 1)).xyz;
	if (dot(viewLine, normalMat * g_Face_Normal[NormalAID.y]) <= 0.0) {
		f_line_build(gl_in[1].gl_Position, gl_in[2].gl_Position, vColor[1], vColor[2], lineWidth[1], lineWidth[2]);
	}

	viewLine = vCamera[0][1] - (vTranformMat[2] * vec4(g_Face_Center[CenterAID.z], 1)).xyz;
	if (dot(viewLine, normalMat * g_Face_Normal[NormalAID.z]) <= 0.0) {
		f_line_build(gl_in[2].gl_Position, gl_in[0].gl_Position, vColor[2], vColor[0], lineWidth[2], lineWidth[0]);
	}
}



